#include "ad7190_helper.h"

// 模块内方法声明
void _ad7190_init(AD7190* thiz);
void _ad7190_reset(AD7190* thiz);
u32 _ad7190_read(u8 from_register);
void _ad7190_write(u32 data, u8 to_register);
ADBuffer* _ad7190_create_buffer(AD7190* thiz, u16 size);
AD7190Data _adbuffer_read(ADBuffer* thiz, u8 channel);
Interator* _adbuffer_create_interator(ADBuffer* thiz);

// 模块接口实现
float AD7190_Standardize_Voltage(u32 data, float voltage)
{
	float d = 0.0;
	float v = 0.0;
	AD7190* ad7190 = AD7190_Get_Instance();
	
	d = data;
	d = ad7190->setting->polarity == UnPolarity ? d : d-0x800000;
	v = d*voltage;
	v = ad7190->setting->polarity == UnPolarity ? v/0xffffff : v/0x800000;
	
	return v;
}

AD7190* AD7190_Get_Instance()
{
	static AD7190* ad7190;
	if(ad7190)
	{
		return ad7190;
	}
	ad7190                = (AD7190*) malloc(sizeof(AD7190));
	ad7190->setting       = (ADSetting*) malloc(sizeof(ADSetting));
	ad7190->init          = _ad7190_init;
	ad7190->reset         = _ad7190_reset;
	ad7190->read          = _ad7190_read;
	ad7190->write         = _ad7190_write;
	ad7190->create_buffer = _ad7190_create_buffer;
	return ad7190;
}

// 模块内方法实现
void _adbuffer_set_scope(ADBuffer* thiz)
{
	AD7190* ad7190 		 = AD7190_Get_Instance();
	Interator* interator = thiz->create_interator(thiz);
	u32 cru_data         = interator->next(interator);
	u32 distance_max     = 0;
	u32 distance         = 0;
	
	for( ; cru_data != ERROR_DATA; cru_data = interator->next(interator))
	{
		if(ad7190->setting->polarity == BiPolarity)
		{
			distance = (cru_data < 0x800000) ? (0x800000 - cru_data) : (cru_data - 0x800000);
		}else
		{
			distance = cru_data - 0x800000;
		}
		distance_max = (distance_max < distance) ? distance : distance_max;
	}
	
	free(interator);
	thiz->scope = distance_max;
}

void _ad7190_init(AD7190* thiz)
{
	AD7190_Init(thiz->setting->channel,
				thiz->setting->gain,
				thiz->setting->polarity,
				BuffOn,
				ContinuousConversionMode,
				Sinc4,
				thiz->setting->outputDataRate);
}

void _ad7190_reset(AD7190* thiz)
{
	AD7190_Reset();
}
u32 _ad7190_read(u8 from_register)
{
	return AD7190_Read(from_register).data;
}
void _ad7190_write(u32 data, u8 to_register)
{
	AD7190_Write(data, to_register);
} 

AD7190Data _adbuffer_read(ADBuffer* thiz, u8 channel)
{
	Queue* datas = thiz->datas;
	AD7190Data data = AD7190_Read(DataRegister);

	if(data.data == UnavailableData)
	{
		return data;
	}
	
	if((data.status + 1) != channel)
	{
		return data;
	}
	// buffer已满
	if(datas->length == thiz->size)
	{
		datas->poll(datas);
	}

	datas->push(datas, data.data);
	_adbuffer_set_scope(thiz);
	return data;
}

ADBuffer* _ad7190_create_buffer(AD7190* thiz, u16 size)
{
	static ADBuffer* ad_buffer;
	if(ad_buffer)
	{
		return ad_buffer;
	}
	ad_buffer = (ADBuffer*) malloc(sizeof(ADBuffer));
	ad_buffer->datas = create_queue();
	ad_buffer->size = size;
	ad_buffer->read = _adbuffer_read;
	ad_buffer->create_interator = _adbuffer_create_interator;
	return ad_buffer;
}
Interator* _adbuffer_create_interator(ADBuffer* thiz)
{
	return thiz->datas->create_interator(thiz->datas);
}
